import React, { useEffect, useMemo } from "react";
import { Row, Col, BackTop } from "antd";
import { Helmet } from 'react-helmet';
import { useParams } from 'react-router-dom';
import { observer } from 'mobx-react';

import clientAxiosInstence from '../request';
import serverAxiosInstance from '../../serverRender/request';
import { useStores } from '../store/store';
import Footer from "./components/Footer";
import Header from "./components/Header";
import RenderHtml from "./components/RenderHtml";
import NextAndPrev from "./components/NextAndPrev";
import Comment from "./components/Comment";
import RecentBlogs from "../blog/components/RecentBlogs";

import { MAX_COUNT } from "../lib/config";
import { getBlogContent, getBlogComments, getBlogList } from "../lib/httpReq";
import { markdownParser, createElm } from "../helper/helper";
import baseStyle from "../helper/baseStyle";
import "./CSS/App.css";

function App() {
    const {
        blogInfo,
        nextAndPrev,
        postComment,
        comments,
        // eslint-disable-next-line no-shadow
        getBlogContent,
    } = useStores('blogContent');

    const { recentBlogs, getNewBlogList } = useStores('blogList');
    const { blogId } = useParams();

    useEffect(() => {
        if (Object.keys(blogInfo).length === 0) {
            getBlogContent(blogId || '', clientAxiosInstence, true);
        }
        if (recentBlogs.length === 0) {
            getNewBlogList(0, clientAxiosInstence);
        }
    }, []);

    const hasBlogInfo = useMemo(() => (
        Object.keys(blogInfo).length > 0
    ), [blogInfo]);

    const parseHtml = useMemo(() => {
        if (typeof blogInfo.content === 'string') {
            return markdownParser.render(blogInfo.content);
        }
        return markdownParser.render('');
    }, [blogInfo]);

    const getCommentInfo = useMemo(() => ({
        _id: blogInfo._id,
        title: blogInfo.title,
    }), [blogInfo._id, blogInfo.title]);

    useEffect(() => {
        if (blogInfo && blogInfo.codeStyle && blogInfo.style) {
            createElm(
                ["style", "style", "style"],
                [baseStyle, blogInfo.codeStyle, blogInfo.style],
                document.head,
            );
        }
    }, [blogInfo]);

    return (
        <>
            <Helmet>
                <title>博客详情页 - {blogInfo.title}</title>
                <meta name="description" content={`多云转晴，博客详情页 - ${blogInfo.title}`} />
            </Helmet>
            <Row id="nice-rich-text-box">
                <BackTop id="back-top">回到顶部</BackTop>
                <Col lg={14} md={18} sm={24} className="content-wrapper">
                    <Header title={blogInfo.title} />
                    { hasBlogInfo ? (
                        <div className="wrapper">
                            <RenderHtml parseHtml={parseHtml} />
                            <Footer blogInfo={blogInfo} />
                            <NextAndPrev nextAndPrev={nextAndPrev} />
                            <Comment
                                blogInfo={getCommentInfo}
                                postComment={postComment}
                                comments={comments}
                            />
                            <RecentBlogs recentBlogs={recentBlogs} />
                        </div>
                    ) : "" }
                </Col>
            </Row>
        </>
    );
}

App.loadData = (store, match) => {
    const { blogId } = match.params;
    return Promise.all([
        getBlogContent(blogId || '', serverAxiosInstance),
        getBlogList(0, MAX_COUNT, "", serverAxiosInstance),
    ]).then((responses) => {
        const { result } = responses[0].data.data;
        const { _id } = result.result;

        store.blogContent.setBlogInfo(result.result);
        store.blogContent.setNextAndPrev(result.nextAndPrev);
        store.blogList.setRecentBlogs(responses[1].data.data.result);
        return getBlogComments(_id, serverAxiosInstance).then((res) => {
            const comments = res.data.data;
            store.blogContent.setComments(comments);
        }).catch((err) => err);
    }).catch();
};

export default observer(App);
